package com.example.juc.controller;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;

/**
 * @author jl
 * @since 2021/10/10 13:44
 */
class MyVar {
    public volatile Boolean isInit = Boolean.FALSE;
    AtomicReferenceFieldUpdater fieldUpdater = AtomicReferenceFieldUpdater.newUpdater(MyVar.class, Boolean.class, "isInit");

    public void init(MyVar myVar) {
        if (fieldUpdater.compareAndSet(myVar, Boolean.FALSE, Boolean.TRUE)) {
            System.out.println(Thread.currentThread().getName() + " --- start init");
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            ;
            System.out.println(Thread.currentThread().getName() + " --- end init");
        } else {
            System.out.println(Thread.currentThread().getName() + " --- 竞争失败，已经有线程在修正中");
        }
    }
}

/**
 * 多线程并发调用一个类的初始化方法，要求只能初始化一次
 */
public class AtomicReferenceFieldUpdaterDemo {
    public static void main(String[] args) {
        MyVar myVar = new MyVar();
        for (int i = 1; i < 5; i++) {
            new Thread(() -> {
                myVar.init(myVar);
            }, i + "").start();
        }
    }
}
